import { validateXML } from '@/utils/validateXML.js';
import React, { useState, useRef, useMemo, useReducer } from 'react';
import { createModel } from 'hox';
import { message as antMessage } from 'antd';
import {
  addCustomMessage,
  updateCustomMessage,
  getCustomMessage,
  deleteCustomMessage,
  getContent,
  getPlaceHolder,
} from './service.js';
import { useRequest } from '@umijs/hooks';
import vkbeautify from 'vkbeautify';

const reducer = (state, action) => {
  switch (action.type) {
    case 'updateState':
      return { ...state, ...action.payload };
    default:
      throw new Error();
  }
};

class Fields {
  sendMessage = '';
  responseMessage = '';
}

function xmlContent() {
  const initState = useMemo(() => new Fields(), []);

  const [message, dispatch] = useReducer(reducer, {
    ...initState,
  });
  const setMessage = payload => {
    dispatch({ type: 'updateState', payload: { ...payload } });
  };

  const format = () => {
    const sendCode = vkbeautify.xml(message.sendMessage.replace(/\s/g, ' '));
    const responseCode = vkbeautify.xml(message.responseMessage.replace(/\s/g, ' '));
    if (sendCode !== message.sendMessage) {
      setMessage({ sendMessage: sendCode });
    }
    if (responseCode !== message.responseMessage) {
      setMessage({ responseMessage: responseCode });
    }
  };
  const clear = () => {
    setMessage({ sendMessage: '', responseMessage: '' });
  };

  const save = async (state, run) => {
    const deviceType = JSON.parse(localStorage.getItem('deviceType'));
    if (!state.messageName) {
      antMessage.error('请填写报文名称！');
      return;
    }
    if (!deviceType.id) {
      antMessage.error('请选择设备类型！');
      return;
    }
    let sendValidate = {};
    let responseValidate = {};

    if (message.sendMessage.replace(/\s/g, '') === '') {
      antMessage.error('请求报文内容不能为空！');
      return;
    } else {
      sendValidate = validateXML(message.sendMessage);
    }

    if (message.responseMessage.replace(/\s/g, '') === '') {
      responseValidate.error_code = 0;
    } else {
      responseValidate = validateXML(message.responseMessage);
    }

    if (sendValidate.error_code === 0 && responseValidate.error_code === 0) {
      let res;
      if (state.isAddMode) {
        res = await addCustomMessage({
          name: state.messageName,
          msgType: state.msgType,
          requestXml: message.sendMessage.replace(/\s/g, ' '),
          responseXml: message.responseMessage.replace(/\s/g, ' '),
          fsuTypeId: deviceType.id,
        });
      } else {
        res = await updateCustomMessage({
          name: state.messageName,
          id: state.selectedRow.id,
          msgType: state.msgType,
          requestXml: message.sendMessage.replace(/\s/g, ' '),
          responseXml: message.responseMessage.replace(/\s/g, ' '),
        });
      }
      if (res.result) {
        antMessage.success('保存成功');
        run({ fsuTypeId: deviceType.id });
      } else {
        antMessage.error(res.msg);
      }
    } else {
      antMessage.error('xml格式错误！');
    }
  };
  return {
    save,
    clear,
    format,
    message,
    setMessage,
  };
}
const useXmlContent = createModel(xmlContent);

class Field {
  isAddMode = false;
  checkedList = [];
  indeterminate = false;
  checkAll = false;
  selectedIndex = null;
  selectedRow = {};
  messageName = '';
  msgType = 0;
  placeHolderArray = [];
  editorDoc = {};
  contextMenuData = {};
  contextMenuPosition = { left: 0, top: 0 };
  contextMenuVisible = false;
}
function useMessageList() {
  const { clear, save, format, message, setMessage } = useXmlContent();
  const field = new Field();
  const [state, dispatch] = useState({
    ...field,
  });
  const clearAll = () => {
    clear();
    dispatch({ ...field });
  };
  const setState = payload => {
    dispatch(prevState => {
      return { ...prevState, ...payload };
    });
  };

  const setXmlContents = data => {
    setMessage({
      sendMessage: data?.requestXml ? vkbeautify.xml(data.requestXml.replace(/\s/g, ' ')) : '',
      responseMessage: data?.responseXml
        ? vkbeautify.xml(data.responseXml.replace(/\s/g, ' '))
        : '',
    });
  };
  const add = () => {
    clear();
    setState({ isAddMode: true, selectedIndex: null, selectedRow: {}, messageName: '' });
  };
  //获取所有字段的占位符
  const placeHolderProps = useRequest(getPlaceHolder, {
    manual: true,
    onSuccess: (res, params) => {
      if (res.result) {
        res?.data && setState({ placeHolderArray: res.data });
      }
    },
  });
  //获取当前xml内容
  const currentCustomProps = useRequest(getContent, {
    manual: true,
    cacheKey: 'xmlContent',
    onSuccess: (res, params) => {
      if (res.result) {
        res?.data && setXmlContents(res.data);
      }
    },
  });
  const remove = async params => {
    let res = await deleteCustomMessage(params);
    if (res.result) {
      run({ fsuTypeId: JSON.parse(localStorage.getItem('deviceType') || {}).id });
      clear();
      setState({
        checkedList: [],
        selectedIndex: null,
        selectedRow: {},
        checkAll: false,
        indeterminate: false,
      });
    }
  };
  const getXmlContent = id => {
    currentCustomProps.run({ id });
  };

  const { loading, run, data } = useRequest(getCustomMessage, {
    manual: true,
    cacheKey: 'allCustomMessage',
    onSuccess: async (result, params) => {
      if (result && state.selectedIndex === null) {
        const data = result?.data;
        if (data && data[0]) {
          let res = await currentCustomProps.run({ id: data[0].id });
          await setState({
            isAddMode: false,
            selectedIndex: 0,
            selectedRow: data[0],
            messageName: data[0].name,
            msgType: data[0].msgType,
          });

          //设置checked列表
        } else {
          setXmlContents({});
          setState({
            isAddMode: true,
            selectedIndex: null,
            selectedRow: {},
            msgType: 0,
            messageName: '',
          });
        }
      }
    },
  });

  return {
    add,
    run,
    state: {
      ...state,
      data: data?.data || [],
      message,
    },
    remove,
    save,
    setMessage,
    clear,
    format,
    setState,
    clearAll,
    placeHolderProps,
    getXmlContent,
    setXmlContents,
  };
}

export default createModel(useMessageList);
